package com.neuedu.service.impl;

import com.neuedu.service.MinioService;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

@Service
public class MinioServiceImpl implements MinioService {
    @Resource
    MinioClient minioClient;
    @Override
    public String mianshi(Long login_id, byte[] bytes, String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        StringBuilder builder = new StringBuilder();
        builder.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")));
        Random random = new Random(login_id);
        for (int i = 0; i < 5; i++) {
            builder.append(random.nextInt(0,10));
        }
        builder.append(".mp3");
        BucketExistsArgs bucketArgs = BucketExistsArgs.builder()
                .bucket(bucket)
                .build();
        if (!minioClient.bucketExists(bucketArgs)) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucket).build());
            minioClient.setBucketPolicy(SetBucketPolicyArgs
                    .builder()
                    .bucket(bucket)
                    .config(String.format("""
                            {
                            	"Version": "2012-10-17",
                            	"Statement": [{
                            		"Effect": "Allow",
                            		"Principal": {
                            			"AWS": ["*"]
                            		},
                            		"Action": ["s3:GetBucketLocation", "s3:ListBucket", "s3:ListBucketMultipartUploads"],
                            		"Resource": ["arn:aws:s3:::%s"]
                            	}, {
                            		"Effect": "Allow",
                            		"Principal": {
                            			"AWS": ["*"]
                            		},
                            		"Action": ["s3:PutObject", "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:ListMultipartUploadParts"],
                            		"Resource": ["arn:aws:s3:::%s/*"]
                            	}]
                            }
                            """, bucket, bucket))
                    .build());
        }
        PutObjectArgs args = PutObjectArgs.builder()
                .contentType("audio/mp3")
                .object(builder.toString())
                .bucket(bucket)
                .stream(new ByteArrayInputStream(bytes), bytes.length, 0)
                .build();
        minioClient.putObject(args);
        return "/" + bucket + "/" + builder.toString();
    }

    @Override
    public void deleteObject(String bucketName, String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build()
        );
    }
    @Override
    public void clearBucket(String bucketName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        if (minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
                    .bucket(bucketName)
                    .recursive(true).build());
            for (Result<Item> result : results) {
                deleteObject(bucketName, result.get().objectName());
            }
        }
    }
}
